package com.zhonghui.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhonghui.common.core.result.FwResult;
import com.zhonghui.common.core.utils.RedisUtils;
import com.zhonghui.dto.PageDto;
import com.zhonghui.dto.ProductCreateDto;
import com.zhonghui.mapper.ProductMapper;
import com.zhonghui.model.Product;
import com.zhonghui.model.ProductDetail;
import com.zhonghui.service.ProductService;
import com.zhonghui.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.Banner;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: FL
 * @create: 2024 2024/5/3 14:49
 */
@Service
@Slf4j
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductMapper productMapper;
    // 用于处理 JSON 数据
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 获取商品分类
     */
    @Override
    public FwResult<List<CategoryVo>> getCategory() {
        List<CategoryVo> category = getCategoryTree();
        if (category.isEmpty()) {
            return FwResult.failedMsg("没有分类");
        }
        return FwResult.ok(category);

    }

    public List<CategoryVo> getCategoryTree() {
        // 获取顶级分类
        List<CategoryVo> topLevelCategories = productMapper.selectCategoriesByParentId(0L);
        // 构建分类树
        buildCategoryTree(topLevelCategories);
        return topLevelCategories;
    }

    private void buildCategoryTree(List<CategoryVo> categories) {
        for (CategoryVo category : categories) {
            // 获取子分类
            List<CategoryVo> children = productMapper.selectCategoriesByParentId(category.getId());
            // 递归构建子分类树
            buildCategoryTree(children);
            // 设置子分类
            category.setTreeList(children);
        }
    }

    /**
     * 获取热门商品
     *
     * @param pageDto
     * @return
     */
    @Override
    public FwResult<ProductHotVo> getHot(PageDto pageDto) {
        List<Product> hot = productMapper.getHot(pageDto);
        if (hot.isEmpty()) {
            log.warn("没有商品");
            return FwResult.failedMsg("没有商品");
        }
        List<ProductRecordHotVo> recordHot = new ArrayList<>();
        // 将商品信息转换为vo
        hot.forEach(product -> {
            ProductRecordHotVo productRecordHotVo = new ProductRecordHotVo();
            BeanUtils.copyProperties(product, productRecordHotVo);
            recordHot.add(productRecordHotVo);
        });
        ProductHotVo productHotVo = new ProductHotVo();
        productHotVo.setRecords(recordHot);
        productHotVo.setTotal(hot.size());
        productHotVo.setSize(pageDto.getSize());
        productHotVo.setCurrent(pageDto.getCurrent());
        productHotVo.setPages(hot.size() / pageDto.getSize());

        return FwResult.ok(productHotVo);
    }

    /**
     * 获取所有商品(分页)
     *
     * @param pageDto
     * @return
     */
    @Override
    public FwResult getAllProduct(PageDto pageDto) {
        try {
            // 在查询前应用分页设置
            PageHelper.startPage(pageDto.getCurrent(), pageDto.getSize());

            // 分页查询所有商品
            List<Product> products = productMapper.getAllProduct(pageDto);

            if (products.isEmpty()) {
                return FwResult.failedMsg("没有商品");
            }

            // 使用Stream API转换为VO，并构建ProductVo
            List<ProductRecordVo> productRecordVos = products.stream()
                    .map(product -> {
                        ProductRecordVo productRecordVo = new ProductRecordVo();
                        BeanUtils.copyProperties(product, productRecordVo);
                        return productRecordVo;
                    })
                    .collect(Collectors.toList());

            // 从PageInfo中获取总记录数，避免重复计数
            PageInfo<Product> pageInfo = new PageInfo<>(products);
            long total = pageInfo.getTotal();
            int totalPages = (int) Math.ceil((double) total / pageDto.getSize());

            ProductVo productVo = ProductVo.builder()
                    .records(productRecordVos)
                    .total(total)
                    .size(pageDto.getSize())
                    .current(pageDto.getCurrent())
                    .pages(totalPages)
                    .build();

            // 简化日志输出，确保信息安全
            log.info("Fetched {} products for display.", products.size());

            return FwResult.ok(productVo);
        } catch (Exception e) {
            log.error("Error occurred while fetching products", e);
            return FwResult.failed("获取商品列表失败");
        }
    }


    @Override
    public FwResult getAllProductByCategory(Long categoryId, PageDto pageDto) {
        // 使用 PageHelper 设置分页参数
        PageHelper.startPage(pageDto.getCurrent(), pageDto.getSize());
        // 分页查询所有指定分类的商品
        List<Product> productList = productMapper.selectAllByCategoryId(categoryId);

        // 将查询结果转换为PageInfo对象
        PageInfo<Product> pageInfo = new PageInfo<>(productList);
        if (pageInfo.getTotal() == 0) {
            return FwResult.failedMsg("没有商品");
        }

        List<Product> products = pageInfo.getList();
        List<ProductRecordVo> productRecordVos = new ArrayList<>(products.size());

        // 将商品信息转换为 VO
        products.forEach(product -> {
            ProductRecordVo productRecordVo = new ProductRecordVo();
            BeanUtils.copyProperties(product, productRecordVo);
            productRecordVos.add(productRecordVo);
        });

        // 构建分页结果
        ProductVo productVo = ProductVo.builder()
                .records(productRecordVos)
                .total(pageInfo.getTotal())
                .size(pageDto.getSize())
                .current(pageDto.getCurrent())
                .pages(pageInfo.getPages())
                .build();

        return FwResult.ok(productVo);
    }

    /**
     * 搜索商品
     */
    @Override
    public FwResult searchByKeyword(String keyword, PageDto pageDto) {
        PageHelper.startPage(pageDto.getCurrent(), pageDto.getSize());
        List<Product> products = productMapper.searchByKeyword(keyword);
        if (products.isEmpty()) {
            log.warn("没有商品");
            return FwResult.failedMsg("没有商品");
        }
        List<ProductRecordVo> productRecordVos = products.stream()
                .map(product -> {
                    ProductRecordVo productRecordVo = new ProductRecordVo();
                    BeanUtils.copyProperties(product, productRecordVo);
                    return productRecordVo;
                })
                .collect(Collectors.toList());
        ProductVo productVo = ProductVo.builder()
                .records(productRecordVos)
                .total((long) products.size())
                .size(pageDto.getSize())
                .current(pageDto.getCurrent())
                .pages(products.size() / pageDto.getSize())
                .build();
        return FwResult.ok(productVo);
    }

    @Override
    public FwResult getAllProductByParentCategory(Long parentCategoryId, PageDto pageDto) {
        PageHelper.startPage(pageDto.getCurrent(), pageDto.getSize());
        List<Product> products = productMapper.selectAllByParentCategoryId(parentCategoryId);
        if (products.isEmpty()) {
            log.warn("没有商品");
            return FwResult.failedMsg("没有商品");
        }
        List<ProductRecordVo> productRecordVos = products.stream()
                .map(product -> {
                    ProductRecordVo productRecordVo = new ProductRecordVo();
                    BeanUtils.copyProperties(product, productRecordVo);
                    return productRecordVo;
                })
                .collect(Collectors.toList());
        ProductVo productVo = ProductVo.builder()
                .records(productRecordVos)
                .total((long) products.size())
                .size(pageDto.getSize())
                .current(pageDto.getCurrent())
                .pages(products.size() / pageDto.getSize())
                .build();
        return FwResult.ok(productVo);
    }

    /**
     * 获取商品详情
     *
     * @param id
     * @return
     */
    @Override
    public FwResult getProduct(Long id) {
        Product product = productMapper.getProduct(id);
        ProductDetail productDetail = productMapper.getProductDetail(id);
        if (product == null || productDetail == null) {
            log.error("商品不存在");
            return FwResult.urlNotFoundMsg("商品不存在");
        }
        ProductDetailVo productDetailVo = ProductDetailVo.builder()
                .id(productDetail.getProductId())
                .name(product.getName())
                .subTitle(product.getSubTitle())
                .price(product.getPrice())
                .stock(product.getStock())
                .rotation(productDetail.getRotation())
                .param(productDetail.getParam())
                .detail(productDetail.getDetail())
                .build();

//        log.info("查询的商品详情:{}", productDetailVo);
        return FwResult.ok(productDetailVo);
    }


    @Override
    public FwResult addProduct(ProductCreateDto productCreateDto) {
        log.info("productCreateDto:{}", productCreateDto);


//        查询活动名在数据库是否存在，如果不存在则抛出错误，如果存在则直接添加商品
        String activityName = productCreateDto.getActivityName();
        //        查询分类名在数据库是否存在，如果不存在则抛出错误，如果存在则直接添加商品


        CategoryVo category = productMapper.getCategoryById(productCreateDto.getSubCategoryId());
        if (category == null) {
            log.error("分类不存在");
            //抛出错误
            return FwResult.validationMsg("分类不存在");
        }


        Product product = Product.builder()
                .name(productCreateDto.getName())
                .subTitle(productCreateDto.getSubTitle())
                .price(productCreateDto.getPrice())
                .stock(productCreateDto.getStock())
                .mainImage(productCreateDto.getMainImage())
                //将subImages转换为字符串，使用,分隔
                .subImages(String.join(",", productCreateDto.getSubImages()))
                .status(productCreateDto.getStatus())
                .hotFlag(productCreateDto.getHotFlag())
                .categoryId(category.getId())
                .build();
//        添加商品，并获取商品id
        Long a = productMapper.addProduct(product);
        log.info("添加的商品id:{}", product.getId());
        redisUtils.set(product.getId().toString(), product.toString());
        try {

            String paramJson = objectMapper.writeValueAsString(productCreateDto.getParam());

            ProductDetail productDetail = ProductDetail.builder()
                    .productId(product.getId())
                    .detail(productCreateDto.getDetail())
                    .param(paramJson)
                    .rotation(product.getMainImage() + "," + product.getSubImages())
                    .build();

            Integer b = productMapper.addProductDetail(productDetail);
            if (a > 0 && b > 0) {
                log.info("添加成功");
                return FwResult.okMsg("添加成功");
            }

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        log.error("添加失败");
        return FwResult.failedMsg("添加商品失败");
    }

    @Override
    public FwResult getSubcategories(Long categoryId) {
        List<CategoryVo> subcategories = productMapper.selectCategoriesByParentId(categoryId);
        if (subcategories.isEmpty()) {
            log.error("没有子分类");
            return FwResult.failedMsg("没有子分类");
        }
        return FwResult.ok(subcategories);
    }

    @Override
    public FwResult getBanner() {
        List<BannerVo> banners = productMapper.getBanner();
        if (banners.isEmpty()) {
            return FwResult.failedMsg("没有banner");
        } else {
            return FwResult.ok(banners);
        }
    }

    @Override
    public FwResult deleteProduct(Long id) {
        // 从 product 表中删除商品
        int productDeleteCount = productMapper.deleteProduct(id);

        // 从 product_detail 表中删除商品详情
        int productDetailDeleteCount = productMapper.deleteProductDetail(id);

        // 如果两个表的删除操作都成功，则返回成功消息
        if (productDeleteCount > 0 && productDetailDeleteCount > 0) {
            return FwResult.okMsg("删除成功");
        }

        // 如果有任何一个删除操作失败，则返回失败消息
        return FwResult.failedMsg("删除失败");
    }

    @Override
    public FwResult getProductForEdit(Long id) {
        Product product = productMapper.getProduct(id);
        ProductDetail productDetail = productMapper.getProductDetail(id);

        if (product == null || productDetail == null) {
            log.error("商品不存在");
            return FwResult.urlNotFoundMsg("商品不存在");
        }

        ProductCreateDto productCreateDto = new ProductCreateDto();
        // 将 Product 和 ProductDetail 的属性拷贝到 DTO
        productCreateDto.setName(product.getName());
        productCreateDto.setSubTitle(product.getSubTitle());
        productCreateDto.setMainImage(product.getMainImage());
        productCreateDto.setSubImages(List.of(product.getSubImages().split(",")));
        productCreateDto.setSubCategoryId(product.getCategoryId());
        productCreateDto.setPrice(product.getPrice());
        productCreateDto.setStock(product.getStock());
        productCreateDto.setStatus(product.getStatus());
        productCreateDto.setHotFlag(product.getHotFlag());
        productCreateDto.setDetail(productDetail.getDetail());

        try {
            // 将参数 JSON 转换为对象
            JsonNode paramNode = objectMapper.readTree(productDetail.getParam());
            productCreateDto.setParam(paramNode);
        } catch (JsonProcessingException e) {
            log.error("JSON解析失败", e);
        }

        return FwResult.ok(productCreateDto);
    }

    @CacheEvict(value = "product", key = "#productCreateDto.id")
    @Override
    public FwResult updateProduct(ProductCreateDto productCreateDto) {
        Long productId = productCreateDto.getId();
        if (productId == null) {
            log.error("商品ID为空");
            return FwResult.validationMsg("商品ID不能为空");
        }

        // 查询商品是否存在
        Product existingProduct = productMapper.getProduct(productId);
        if (existingProduct == null) {
            log.error("商品不存在");
            return FwResult.validationMsg("商品不存在");
        }

        // 更新商品
        Product product = Product.builder()
                .id(productId)
                .name(productCreateDto.getName())
                .subTitle(productCreateDto.getSubTitle())
                .price(productCreateDto.getPrice())
                .stock(productCreateDto.getStock())
                .mainImage(productCreateDto.getMainImage())
                .subImages(String.join(",", productCreateDto.getSubImages()))
                .status(productCreateDto.getStatus())
                .hotFlag(productCreateDto.getHotFlag())
                .categoryId(productCreateDto.getSubCategoryId())
                .updateTime(java.time.LocalDateTime.now())
                .build();
        int productUpdateCount = productMapper.updateProduct(product);

        // 更新商品详情
        try {
            String paramJson = objectMapper.writeValueAsString(productCreateDto.getParam());

            ProductDetail productDetail = ProductDetail.builder()
                    .productId(productId)
                    .detail(productCreateDto.getDetail())
                    .param(paramJson)
                    .rotation(product.getMainImage() + "," + product.getSubImages())
                    .updateTime(java.time.LocalDateTime.now())
                    .build();
            int productDetailUpdateCount = productMapper.updateProductDetail(productDetail);

            if (productUpdateCount > 0 && productDetailUpdateCount > 0) {
                // **清除旧缓存**
                redisUtils.del(String.valueOf(productId)); // 假设你使用 Redis
                return FwResult.okMsg("商品更新成功");
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        log.error("商品更新失败");
        return FwResult.failedMsg("商品更新失败");
    }


}
